home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 12 / Example 12.5 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  7.3 KB  |  283 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 12.5: Environment Maps                            //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "heightMap.h"
  10. #include "terrain.h"
  11. #include "camera.h"
  12. #include "mouse.h"
  13. #include "skybox.h"
  14.  
  15. class APPLICATION
  16. {
  17.     public:
  18.         APPLICATION();
  19.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  20.         HRESULT Update(float deltaTime);
  21.         HRESULT Render();
  22.         HRESULT Cleanup();
  23.         HRESULT Quit();
  24.         DWORD FtoDword(float f){return *((DWORD*)&f);}
  25.  
  26.     private:
  27.         TERRAIN m_terrain;
  28.         MOUSE m_mouse;
  29.         SKYBOX *m_pSkybox;
  30.         bool m_wireframe;
  31.  
  32.         DWORD m_time, m_snapTime;
  33.         int m_fps, m_lastFps;
  34.         INTPOINT m_lastM;
  35.         D3DXVECTOR3 m_rot;
  36.         ID3DXFont *m_pFont;
  37.  
  38.         IDirect3DDevice9* m_pDevice; 
  39.         HWND m_mainWindow;
  40. };
  41.  
  42. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  43. {
  44.     APPLICATION app;
  45.  
  46.     if(FAILED(app.Init(hInstance, 800, 600, true)))return 0;
  47.  
  48.     MSG msg;
  49.     memset(&msg, 0, sizeof(MSG));
  50.     int startTime = timeGetTime(); 
  51.  
  52.     while(msg.message != WM_QUIT)
  53.     {
  54.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  55.         {
  56.             ::TranslateMessage(&msg);
  57.             ::DispatchMessage(&msg);
  58.         }
  59.         else
  60.         {    
  61.             int t = timeGetTime();
  62.             float deltaTime = (t - startTime)*0.001f;
  63.  
  64.             app.Update(deltaTime);
  65.             app.Render();
  66.  
  67.             startTime = t;
  68.         }
  69.     }
  70.  
  71.     app.Cleanup();
  72.  
  73.     return msg.wParam;
  74. }
  75.  
  76. APPLICATION::APPLICATION()
  77. {
  78.     m_pDevice = NULL; 
  79.     m_mainWindow = 0;
  80.     m_wireframe = false;
  81.     srand(GetTickCount());
  82.     m_fps = m_lastFps = 0;
  83.     m_time = m_snapTime = GetTickCount();
  84.     m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  85. }
  86.  
  87. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  88. {
  89.     debug.Print("Application initiated");
  90.  
  91.     //Create Window Class
  92.     WNDCLASS wc;
  93.     memset(&wc, 0, sizeof(WNDCLASS));
  94.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  95.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  96.     wc.hInstance     = hInstance;
  97.     wc.lpszClassName = "D3DWND";
  98.  
  99.     //Register Class and Create new Window
  100.     RegisterClass(&wc);
  101.     m_mainWindow = CreateWindow("D3DWND", "Example 12.5: Environment Maps", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  102.     SetCursor(NULL);
  103.     ShowWindow(m_mainWindow, SW_SHOW);
  104.     UpdateWindow(m_mainWindow);
  105.  
  106.     //Create IDirect3D9 Interface
  107.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  108.  
  109.     if(d3d9 == NULL)
  110.     {
  111.         debug.Print("Direct3DCreate9() - FAILED");
  112.         return E_FAIL;
  113.     }
  114.  
  115.     //Check that the Device supports what we need from it
  116.     D3DCAPS9 caps;
  117.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  118.  
  119.     //Hardware Vertex Processing or not?
  120.     int vp = 0;
  121.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  122.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  123.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  124.  
  125.     //Check vertex & pixelshader versions
  126.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  127.     {
  128.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  129.     }
  130.  
  131.     //Set D3DPRESENT_PARAMETERS
  132.     D3DPRESENT_PARAMETERS d3dpp;
  133.     d3dpp.BackBufferWidth            = width;
  134.     d3dpp.BackBufferHeight           = height;
  135.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  136.     d3dpp.BackBufferCount            = 1;
  137.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  138.     d3dpp.MultiSampleQuality         = 0;
  139.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  140.     d3dpp.hDeviceWindow              = m_mainWindow;
  141.     d3dpp.Windowed                   = windowed;
  142.     d3dpp.EnableAutoDepthStencil     = true; 
  143.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  144.     d3dpp.Flags                      = 0;
  145.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  146.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  147.  
  148.     //Create the IDirect3DDevice9
  149.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  150.                                  vp, &d3dpp, &m_pDevice)))
  151.     {
  152.         debug.Print("Failed to create IDirect3DDevice9");
  153.         return E_FAIL;
  154.     }
  155.  
  156.     //Release IDirect3D9 interface
  157.     d3d9->Release();
  158.  
  159.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  160.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  161.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  162.  
  163.     LoadObjectResources(m_pDevice);
  164.     m_terrain.Init(m_pDevice, INTPOINT(100,100));
  165.  
  166.     m_mouse.InitMouse(m_pDevice, m_mainWindow);
  167.     m_lastM = m_mouse;
  168.  
  169.     //Set sampler state
  170.     for(int i=0;i<8;i++)
  171.     {
  172.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  173.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  174.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  175.     }
  176.  
  177.     m_pSkybox = new SKYBOX(m_pDevice, "", 500.0f);
  178.     m_pSkybox->GenerateEnvironmentMap(m_terrain.GetWorldPos(m_terrain.m_size / 2) + D3DXVECTOR3(0.0f, 10.0f, 0.0f), true, m_terrain);
  179.  
  180.     return S_OK;
  181. }
  182.  
  183. HRESULT APPLICATION::Update(float deltaTime)
  184. {
  185.     //Control camera
  186.     m_mouse.Update();
  187.     
  188.     //Update Camera
  189.     if(m_mouse != m_lastM)
  190.     {
  191.         m_rot.y -= (m_lastM.x - m_mouse.x) * 0.01f;
  192.         m_rot.z += (m_lastM.y - m_mouse.y) * 0.01f;
  193.         m_lastM = m_mouse;
  194.     }
  195.  
  196.     if(KEYDOWN(VK_SPACE))
  197.     {        
  198.         m_terrain.GenerateRandomTerrain(9);
  199.         m_pSkybox->GenerateEnvironmentMap(m_terrain.GetWorldPos(m_terrain.m_size / 2) + D3DXVECTOR3(0.0f, 10.0f, 0.0f), true, m_terrain);
  200.     }
  201.     else if(KEYDOWN(VK_ESCAPE))
  202.     {
  203.         Quit();
  204.     }
  205.  
  206.     return S_OK;
  207. }    
  208.  
  209. HRESULT APPLICATION::Render()
  210. {
  211.     // Clear the viewport
  212.     m_pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0L );
  213.  
  214.     //FPS Calculation
  215.     m_fps++;
  216.     if(GetTickCount() - m_time > 1000)
  217.     {
  218.         m_lastFps = m_fps;
  219.         m_fps = 0;
  220.         m_time = GetTickCount();
  221.     }
  222.  
  223.     //Set camera
  224.     D3DXMATRIX r;
  225.     D3DXMatrixRotationYawPitchRoll(&r, m_rot.y, m_rot.x, m_rot.z);
  226.     D3DXVECTOR3 focus = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
  227.     D3DXVec3TransformNormal(&focus, &focus, &r);
  228.     D3DXVec3Normalize(&focus, &focus);
  229.  
  230.     D3DXMATRIX view, proj, world, identity;
  231.     D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &focus, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  232.     D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.4f, 1.33333f, 0.01f, 1000.0f);
  233.     D3DXMatrixIdentity(&identity);
  234.  
  235.     m_pDevice->SetTransform(D3DTS_WORLD, &identity);
  236.     m_pDevice->SetTransform(D3DTS_VIEW, &view);
  237.     m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  238.  
  239.     // Begin the scene 
  240.     if(SUCCEEDED(m_pDevice->BeginScene()))
  241.     {
  242.         if(m_wireframe)m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);    
  243.         else m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
  244.  
  245.         m_pSkybox->Render(D3DXVECTOR3(0.0f, 0.0f, 0.0f));
  246.         m_mouse.Paint();
  247.  
  248.         RECT r = {10, 10, 0, 0};
  249.         m_pFont->DrawText(NULL, "Space: Randomize Terrain", -1, &r, DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  250.  
  251.         // End the scene.
  252.         m_pDevice->EndScene();
  253.         m_pDevice->Present(0, 0, 0, 0);
  254.     }
  255.  
  256.     return S_OK;
  257. }
  258.  
  259. HRESULT APPLICATION::Cleanup()
  260. {
  261.     try
  262.     {
  263.         m_terrain.Release();
  264.         UnloadObjectResources();
  265.  
  266.         if(m_pSkybox)delete m_pSkybox;
  267.  
  268.         m_pFont->Release();
  269.         m_pDevice->Release();
  270.  
  271.         debug.Print("Application terminated");
  272.     }
  273.     catch(...){}
  274.  
  275.     return S_OK;
  276. }
  277.  
  278. HRESULT APPLICATION::Quit()
  279. {
  280.     ::DestroyWindow(m_mainWindow);
  281.     ::PostQuitMessage(0);
  282.     return S_OK;
  283. }